﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Granite.Eventing;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Granite.Commons.Tests.Eventing
{
	[TestClass]
	public class ItemPropertyChangedEventManagerTests
	{
		[TestMethod]
		public void ItemPropertyChangedEventManager_Test1()
		{
			var mock = new Mock();
			var manager = new ItemPropertyChangedEventManager(mock);
			try
			{
				manager.AddHandler(null);
				Assert.Fail("Expected an ArgumentNullException");
			}
			catch (ArgumentNullException ex)
			{
				Assert.AreEqual("eventHandler", ex.ParamName, "Parameter name is wrong");
			}
		}

		[TestMethod]
		public void ItemPropertyChangedEventManager_Test2()
		{
			var mock = new Mock();
			var manager = new ItemPropertyChangedEventManager(mock);
			try
			{
				manager.RemoveHandler(null);
				Assert.Fail("Expected an ArgumentNullException");
			}
			catch (ArgumentNullException ex)
			{
				Assert.AreEqual("eventHandler", ex.ParamName, "Parameter name is wrong");
			}
		}

		[TestMethod]
		public void ItemPropertyChangedEventManager_Test3()
		{
			var mock = new Mock();
			var manager = new ItemPropertyChangedEventManager(mock);
			var listener1 = new Listener<RelayedEventArgs<PropertyChangedEventArgs>>((s, rea) => { });
			var listener2 = new Listener<RelayedEventArgs<PropertyChangedEventArgs>>((s, rea) => { });
			manager.AddHandler(listener1);
			manager.AddHandler(listener2);
			mock.OnItemPropertyChanged(this, new PropertyChangedEventArgs("X"));
			manager.RemoveHandler(listener2);
			manager.RemoveHandler(listener1);
		}

		[TestMethod]
		public void ItemPropertyChangedEventManager_Test4()
		{
			var mock = new Mock();
			var manager = new ItemPropertyChangedEventManager(mock);

			Action add = () =>
			{
				var listener1 = new Listener<RelayedEventArgs<PropertyChangedEventArgs>>((s, rea) => { });
				manager.AddHandler(listener1);

			};
			add();
			mock.OnItemPropertyChanged(this, new PropertyChangedEventArgs("X"));
			TestUtilities.GCCycle();
			mock.OnItemPropertyChanged(this, new PropertyChangedEventArgs("X"));

		}


		[TestMethod]
		public void ItemPropertyChangedEventManager_Test5()
		{
			try
			{
				var manager = new ItemPropertyChangedEventManager(null);
				Assert.Fail("Expected an ArgumentNullException");
			}
			catch (ArgumentNullException ex)
			{
				Assert.AreEqual("source", ex.ParamName, "Parameter name is wrong");
			}
		}

		class Mock : INotifyItemPropertyChanged
		{

			public event RelayedEventHandler<PropertyChangedEventArgs> ItemPropertyChanged;

			public virtual void OnItemPropertyChanged(object originalSender, PropertyChangedEventArgs ea)
			{
				OnItemPropertyChanged(RelayedEventArgs.Create(originalSender, ea));
			}
			public virtual void OnItemPropertyChanged(RelayedEventArgs<PropertyChangedEventArgs> rea)
			{
				if (ItemPropertyChanged != null)
					ItemPropertyChanged(this, rea);
			}

		}

	}
}



